﻿namespace tinfosvr
{
    using Fleck;
    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.Timers;
    using tinfosvr.Models;

    class WebSocketClient
    {
        private IWebSocketConnection mSocket;
        private Timer mTimer;
        private Timer mNoticeTimer;
        private List<qy_stationinfo> mPlatforms;
        private bool mConnState;
        private int mNoticeTimeInDay;
        private string mUserNo = "";

        public WebSocketClient(IWebSocketConnection conn)
        {
            mSocket = conn;
            mConnState = true;
            mNoticeTimer = new Timer();
            mNoticeTimer.Interval = 1000.0;
            mNoticeTimer.Elapsed += new ElapsedEventHandler(MNoticeTimer_Elapsed);
        }

        public void dispose()
        {
            StopPushTrainTimes();
            mNoticeTimer.Stop();
            mSocket.Close();
        }

        public IWebSocketConnection getSock() => 
            mSocket;

        private void MNoticeTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            mNoticeTimer.Stop();
            try
            {
                if ((((int) DateTime.Now.TimeOfDay.TotalSeconds) >= mNoticeTimeInDay) && !SendTrainNoticeInfo())
                {
                    mNoticeTimer.Start();
                }
            }
            catch (Exception)
            {
            }
        }

        private void MTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            mTimer.Stop();
            try
            {
                SendTrainTimesInfo();
            }
            catch (Exception)
            {
            }
            finally
            {
                if (mConnState)
                {
                    mTimer.Start();
                }
            }
        }

        public void OnClose()
        {
            mConnState = false;
            StopPushTrainTimes();
        }

        public void OnRecvBytes(byte[] data)
        {
        }

        public void OnRecvMsg(string message)
        {
            Console.WriteLine("recv:" + message);
            CmdParam param = null;
            try
            {
                param = JsonConvert.DeserializeObject<CmdParam>(message);
            }
            catch (Exception exception)
            {
                Console.WriteLine("convert cmd json err:" + exception.Message);
                return;
            }
            StopPushTrainTimes();
            if (param.sort == 1)
            {
                mPlatforms = new List<qy_stationinfo>();
                mPlatforms.AddRange((IEnumerable<qy_stationinfo>) TrainTimesUpdater.GetInstance().GetPlatform(param.citycode, param.station_name));
                SendTrainTimesInfo();
                StartPushTrainTimes();
            }
            else if (param.sort == 0)
            {
                try
                {
                    if (param.notice == 1)
                    {
                        NoticeMsg msg = new NoticeMsg();
                        mUserNo = param.userno;
                        string[] strArray = param.station_name.Trim().Replace("，", ",").Split(',', (StringSplitOptions) StringSplitOptions.None);
                        if (strArray.Length < 2)
                        {
                            msg.arrive_status = 0;
                            msg.user_no = param.userno;
                            msg.msg = "设置到站提醒失败了:(";
                            SendObject(msg);
                        }
                        else
                        {
                            mNoticeTimeInDay = (int) DateTime.Now.TimeOfDay.TotalSeconds;
                            string[] strArray2 = strArray;
                            for (int i = 0; i < strArray2.Length; i++)
                            {
                                string text1 = strArray2[i];
                            }
                            mNoticeTimer.Start();
                            msg.arrive_status = 1;
                            msg.user_no = param.userno;
                            msg.msg = "设置到站提醒成功:)";
                            SendObject(msg);
                        }
                    }
                    else if (param.notice == 0)
                    {
                        mNoticeTimer.Stop();
                        mNoticeTimeInDay = 0;
                        NoticeMsg msg2 = new NoticeMsg {
                            arrive_status = 2,
                            msg = "取消到站提醒成功:)",
                            user_no = param.userno
                        };
                        SendObject(msg2);
                    }
                    else
                    {
                        mUserNo = param.userno;
                    }
                }
                catch (Exception exception2)
                {
                    mNoticeTimer.Stop();
                    mNoticeTimeInDay = 0;
                    NoticeMsg msg3 = new NoticeMsg {
                        arrive_status = 0,
                        user_no = param.userno,
                        msg = "竟然设置失败了(╥╯^╰╥), 稍后再试一下吧 :)"
                    };
                    SendObject(msg3);
                    Console.WriteLine("Process cmd err:" + exception2.Message);
                }
            }
        }

        private void SendObject(object obj)
        {
            try
            {
                string message = JsonConvert.SerializeObject(obj);
                if (mSocket.IsAvailable)
                {
                    mSocket.Send(message);
                    Console.WriteLine("send:" + message);
                }
                else
                {
                    object[] objArray1 = new object[] { "conn dead:", mSocket.ConnectionInfo.ClientIpAddress, ":", (int) mSocket.ConnectionInfo.ClientPort };
                    Console.WriteLine(string.Concat((object[]) objArray1));
                    dispose();
                }
            }
            catch (Exception exception)
            {
                Console.WriteLine("send failed:" + exception.Message);
            }
        }

        private bool SendTrainNoticeInfo()
        {
            try
            {
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        private void SendTrainTimesInfo()
        {
            trainTimes times = new trainTimes {
                status = 1,
                msg = "success"
            };
            foreach (qy_stationinfo _stationinfo in mPlatforms)
            {
                data item = new data();
                if(TrainTimesUpdater.GetInstance().UpdateTrainTimesInfo(_stationinfo))
                {
                    item.current_train = _stationinfo.current_train;
                    item.next_train = _stationinfo.next_train;
                }
                item.station_id = _stationinfo.station_id;
                item.platform_id = _stationinfo.id;
                item.direction = _stationinfo.direction;

                times.data.Add(item);
            }
            SendObject(times);
        }

        private void StartPushTrainTimes()
        {
            if (mConnState)
            {
                mTimer = new Timer();
                mTimer.Interval = 1000.0;
                mTimer.Elapsed += new ElapsedEventHandler(MTimer_Elapsed);
                mTimer.Start();
            }
        }

        private void StopPushTrainTimes()
        {
            if (mTimer != null)
            {
                mTimer.Stop();
                mTimer = null;
            }
        }
    }
}

